#ifndef Queue_Thread
#define Queue_Thread

#include "JniMacro.h"
#include "SafeQueue.h"

typedef void *(*Runnable)(void *);

struct RunnableTask {

    public:

    Runnable run;
    void *args;

    RunnableTask(Runnable run, void *args) : run(run), args(args) {}
};

typedef SafeQueue<RunnableTask *> RunnableQueue;

class QueueThread {

    public:

    RunnableQueue *queue = new RunnableQueue([](RunnableTask *&task) -> void {
        DELETE(task)
    });

    bool isWorking = false;

    pthread_t pid;

    QueueThread() {}

    ~QueueThread() {
        delete queue;
    }

    void start() {
        isWorking = true;
        queue->setWorking(true);
        pthread_create(&pid, nullptr, [](void *args) -> void * {
            QueueThread *queueThread = static_cast<QueueThread *>(args);
            RunnableTask *task = nullptr;
            while (queueThread->isWorking) {
                bool result = queueThread->queue->dequeue(task);
                if (result) {
                    task->run(task->args);
                    delete task;
                }
            }
            return nullptr;
        }, this);
    }

    void stop() {
        isWorking = false;
        queue->setWorking(false);
        queue->clear();
    }

    void add(RunnableTask *task) {
        if (!isWorking)return;
        queue->enqueue(task);
    }
};

#endif

